/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package ru.miit.elearning.servlets.pages;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.hibernate.Session;
import ru.miit.elearning.hibernate.dao.CourseDAO;
import ru.miit.elearning.hibernate.dao.HibernateUtil;
import ru.miit.elearning.hibernate.dto.beans.UserBean;
import ru.miit.elearning.hibernate.dao.UserDAO;
import ru.miit.elearning.hibernate.dao.WebLabUtil;
import ru.miit.elearning.hibernate.dto.CurriculumLevel;
import ru.miit.elearning.hibernate.dto.ProfileType;
import ru.miit.elearning.hibernate.dto.UserIdentity;

/**
 *
 * @author Cyclone
 */
public class UsersServlet extends HttpServlet {

    /**
     * Processes requests for both HTTP <code>GET</code> and <code>POST</code> methods.
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    protected void processRequest(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        response.setContentType("text/html;charset=UTF-8");
        //PrintWriter out = response.getWriter();

        Session session = null;

        try {

            int page = 1;
            int rowCount = 10;

            String sort = request.getParameter("sort");

            //TODO What will hapen, if the number of page is #3 with view = 10,
            //and we're changing view to 50 -> only 2 pages. Servlet returns nothing?

            try {
                String pageString = request.getParameter("page");
                if (pageString != null) {
                    page = Integer.parseInt(pageString);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            try {
                String rowNumString = request.getParameter("view");
                if (rowNumString != null) {
                    rowCount = Integer.parseInt(rowNumString);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }

            //session = WebLabUtil.prepareTransaction();
            session = HibernateUtil.getSessionFactory().getCurrentSession();
            session.getTransaction().begin();

            UserDAO userDAO = new UserDAO(session);

            int currentUserId = userDAO.findUserIdByLogin(request.getRemoteUser());

//             /*
            long totalRows = 0;
            if (request.isUserInRole("admin")) {
                totalRows = userDAO.countUsers();
            } else {
                if (request.isUserInRole("tutor")) {
                    totalRows = userDAO.countUsersByTutor(currentUserId);
                }
            }
            int totalPages = new Double(Math.ceil((double) totalRows / rowCount)).intValue();
//             */

            // chack page : [1; totalPages]
            page = Math.min(Math.max(1, page), totalPages);

            List<UserIdentity> userList = null;

            if (request.isUserInRole("admin")) {
                userList = userDAO.findUsersByPage((page - 1) * rowCount, rowCount, sort);
            } else {
                if (request.isUserInRole("tutor")) {
                    userList = userDAO.findUsersByPageByTutor((page - 1) * rowCount, rowCount, sort, currentUserId);
                } else {
                    if (request.isUserInRole("student")) {
                        List<CurriculumLevel> studentCourseList = userDAO.findCoursesByStudentId(currentUserId);
                        if (studentCourseList != null && studentCourseList.size() > 0) {
                            Set<UserIdentity> userSet = new HashSet<UserIdentity>();
                            CourseDAO courseDAO = new CourseDAO(session);
                            for (CurriculumLevel cl : studentCourseList) {
                                userSet.addAll(courseDAO.findStudentsByCourse(cl.getId()));
                            }
                            userSet.remove(userDAO.findUserById(currentUserId));
                            userList = new ArrayList<UserIdentity>(userSet);
                            Collections.sort(userList, new Comparator<UserIdentity>() {
                                public int compare(UserIdentity o1, UserIdentity o2) {
                                    return o1.getName().compareTo(o2.getName());
                                }
                            });

                            totalRows = userList.size();
                            totalPages = new Double(Math.ceil((double) totalRows / rowCount)).intValue();

                            // userList.addAll(userSet);
                        }
                    }
                }
            }

            List<UserBean> userBeanList = new ArrayList<UserBean>();
            for (UserIdentity userIdentity : userList) {
                UserBean userBean = new UserBean();
                userBean.setUserIdentity(userIdentity);

                if (request.isUserInRole("tutor")) {
                    List<CurriculumLevel> courseList = userDAO.findCoursesByStudentIdByTutor(userIdentity.getAccount(), currentUserId);
                    userBean.setCourseList(courseList);
                } else {
                    if(request.isUserInRole("student")) {
                        List<CurriculumLevel> courseList = userDAO.findSharedStudentsCourses(userIdentity.getAccount(), currentUserId);
                        userBean.setCourseList(courseList);
                    }
                }
                userBeanList.add(userBean);
            }



            if (request.isUserInRole("admin")) {
                List<ProfileType> typeList = userDAO.findAllProfileTypes();
                request.setAttribute("typeList", typeList);
            }


            if (request.isUserInRole("tutor")) {
                CourseDAO courseDAO = new CourseDAO(session);
                List<CurriculumLevel> courseList = courseDAO.findCoursesByTutor(courseDAO.findUserIdByLogin(request.getRemoteUser()), null);
                request.setAttribute("courseList", courseList);
            }


            request.setAttribute("page", page);
            request.setAttribute("totalPages", totalPages);
            request.setAttribute("rowCount", rowCount);
            request.setAttribute("totalRows", totalRows);
            request.setAttribute("userBeanList", userBeanList);

            request.getRequestDispatcher("/users.jsp").forward(request, response);
            //WebLabUtil.commitTransaction(session);
            if (session != null && session.isOpen()) {
                session.getTransaction().commit();
            }
        } catch (Exception e) {
            if (session != null && session.isOpen()) {
                session.getTransaction().rollback();
            }
            Logger.getLogger(UsersServlet.class.getName()).log(Level.SEVERE, null, e);
            e.printStackTrace();

            String message = "<p>Произошла ошибка запроса списка пользователей";
            message += WebLabUtil.prepareExceptionRef(request.getSession(), e);
            message += "</p>";
            getServletContext().setAttribute("message", message);

            request.getRequestDispatcher("/users.jsp").forward(request, response);
        } finally {
            //WebLabUtil.closeTransaction(session);
            if (session != null && session.isOpen()) {
                session.close();
            }
        }
    }

    // <editor-fold defaultstate="collapsed" desc="HttpServlet methods. Click on the + sign on the left to edit the code.">
    /**
     * Handles the HTTP <code>GET</code> method.
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        processRequest(request, response);
    }

    /**
     * Handles the HTTP <code>POST</code> method.
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        processRequest(request, response);
    }

    /**
     * Returns a short description of the servlet.
     * @return a String containing servlet description
     */
    @Override
    public String getServletInfo() {
        return "Short description";
    }// </editor-fold>
}
